package com.houhanzhi.service.impl;

import com.houhanzhi.config.RabbitMQConfig;
import com.houhanzhi.controller.request.AccountLoginRequest;
import com.houhanzhi.controller.request.AccountRegisterRequest;
import com.houhanzhi.enums.AuthTypeEnum;
import com.houhanzhi.enums.BizCodeEnum;
import com.houhanzhi.enums.EventMessageTypeEnum;
import com.houhanzhi.enums.SendCodeEnum;
import com.houhanzhi.manager.AccountManager;
import com.houhanzhi.model.AccountDO;
import com.houhanzhi.model.EventMessage;
import com.houhanzhi.model.LoginUser;
import com.houhanzhi.response.JsonData;
import com.houhanzhi.service.AccountService;
import com.houhanzhi.service.NotifyService;
import com.houhanzhi.util.CommonUtil;
import com.houhanzhi.util.IDUtil;
import com.houhanzhi.util.JWTUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.Md5Crypt;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author houhanzhi
 * @since 2025-01-02
 */
@Service
@Slf4j
public class AccountServiceImpl implements AccountService {

    @Autowired
    private NotifyService notifyService;

    @Autowired
    private AccountManager accountManager;

    @Autowired
    private RabbitMQConfig rabbitMQConfig;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    // 免费流量包id
    private static final Long FREE_TRAFFIC_PRODUCT_ID = 1L;


    /**
     * - 手机验证码验证
     * - 密码加密（TODO）
     * - 账号唯一性检查(TODO)
     * - 插入数据库
     * - 新注册用户福利发放(TODO)
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public JsonData register(AccountRegisterRequest request) {
        boolean checkCode = false;
        // 判断验证码
        if (StringUtils.isNotBlank(request.getCode())) {
            checkCode = notifyService.checkCode(SendCodeEnum.USER_REGISTER, request.getPhone(), request.getCode());
        }
        // 验证码错误
        if (!checkCode) {
            return JsonData.buildResult(BizCodeEnum.CODE_ERROR);
        }

        AccountDO accountDO = new AccountDO();
        BeanUtils.copyProperties(request, accountDO);
        // 认证级别
        accountDO.setAuth(AuthTypeEnum.DEFAULT.name());

        // 生成唯一的账号
        accountDO.setAccountNo(Long.valueOf(IDUtil.geneSnowFlakeID().toString()));

        // 设置密码：密钥+盐
        accountDO.setSecret("$1$" + CommonUtil.getStringNumRandom(8));
        String cryptPwd = Md5Crypt.md5Crypt(request.getPwd().getBytes(), accountDO.getSecret());
        accountDO.setPwd(cryptPwd);

        int rows = accountManager.insert(accountDO);
        log.info("rows:{},注册成功:{}",rows,accountDO);

        // 用户注册成功，发放福利
        userRegisterInitTask(accountDO);
        // TODO 分布式事务问题：一旦此处异常，上述将会出现用户注册失败，但是流量包发送成功的现象，出现垃圾数据，但是不影响
        //  当然也可以在消费者端处理，发放流量包的时候查询注册用户是否存在，存在即发送

        return JsonData.buildSuccess();
    }

    /**
     * 用户登陆
     *  1、根据手机号查询
     *  2、判断
     * @param request
     * @return
     */
    @Override
    public JsonData login(AccountLoginRequest request) {
        List<AccountDO> accountDOList = accountManager.findByPhone(request.getPhone());
        if(!CollectionUtils.isEmpty(accountDOList)){
            AccountDO accountDO = accountDOList.get(0);
            String md5Crypt = Md5Crypt.md5Crypt(request.getPwd().getBytes(), accountDO.getSecret());
            if(md5Crypt.equalsIgnoreCase(accountDO.getPwd())) {
                // 生成TOKEN
                LoginUser loginUser = LoginUser.builder().build();
                BeanUtils.copyProperties(accountDO, loginUser);
                String token = JWTUtil.geneJsonWebToken(loginUser);
                return JsonData.buildSuccess(token);
            } else {
                return JsonData.buildResult(BizCodeEnum.ACCOUNT_PWD_ERROR);
            }
        } else {
            return JsonData.buildResult(BizCodeEnum.ACCOUNT_UNREGISTER);
        }
    }


    /**
     *  用户初始化成功后，发放福利：流量包
     * @param accountDO
     */
    private void userRegisterInitTask(AccountDO accountDO) {
        EventMessage eventMessage = EventMessage.builder().messageId(IDUtil.geneSnowFlakeID().toString())
                .accountNo(accountDO.getAccountNo())
                .eventMessageType(EventMessageTypeEnum.TRAFFIC_FREE_INIT.name())
                // 商品id
                .bizId(FREE_TRAFFIC_PRODUCT_ID.toString())
                .build();
        rabbitTemplate.convertAndSend(rabbitMQConfig.getTrafficEventExchange(), rabbitMQConfig.getTrafficFreeInitRoutingKey(), eventMessage);
    }


}
